package club.martaintao.activiti7springbootdemo.controller;

import club.martaintao.activiti7springbootdemo.common.BaseResponse;
import club.martaintao.activiti7springbootdemo.model.LocalUserDetail;
import club.martaintao.activiti7springbootdemo.model.vo.ProcessInstanceVO;
import club.martaintao.activiti7springbootdemo.utils.SecurityUtil;
import org.activiti.api.model.shared.model.VariableInstance;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.model.payloads.StartProcessPayload;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

import static org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId;

@RestController
@RequestMapping("/processInstance")
public class ProcessInstanceController {

    @Autowired
    ProcessRuntime processRuntime;

    @Autowired
    RepositoryService repositoryService;

    @Autowired
    private SecurityUtil securityUtil;


    @GetMapping("/getInstances")
    public BaseResponse getInstances(){
        Page<ProcessInstance> instancePage = processRuntime.processInstances(Pageable.of(0, 100));
        List<ProcessInstance> processInstances = instancePage.getContent();
        processInstances.sort((y,x)->x.getStartDate().toString().compareTo(y.getStartDate().toString()));
        List<ProcessInstanceVO> processInstanceVOS = new ArrayList<>();
        for (ProcessInstance pi :
                processInstances) {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(pi.getProcessDefinitionId()).singleResult();
            processInstanceVOS.add(ProcessInstanceVO.of(pi,processDefinition));
        }
        return BaseResponse.success(processInstanceVOS);
    }


    @PostMapping("/startProcess")
    public BaseResponse startProcess(String processDefinitionKey, String instanceName, @AuthenticationPrincipal LocalUserDetail userDetail){
        ProcessInstance processInstance = null;
        try{
            StartProcessPayload startProcessPayload = ProcessPayloadBuilder.start().withProcessDefinitionKey(processDefinitionKey)
                    .withBusinessKey("123")
                    .withVariable("sponsor",userDetail.getUsername())
                    .withName(instanceName).build();
            processInstance = processRuntime.start(startProcessPayload);
        }catch (Exception e){
            System.out.println(e);
            return BaseResponse.error("开启失败:"+e.getLocalizedMessage());
        }
        return BaseResponse.success(processInstance);
    }

    @PostMapping("/getVariable")
    public BaseResponse getVariable(String instanceId){
        List<VariableInstance> variables = processRuntime.variables(ProcessPayloadBuilder.variables().withProcessInstanceId(instanceId).build());
        return BaseResponse.success(variables);
    }

    @DeleteMapping("/deleteProcess/{instanceId}")
    public BaseResponse deleteProcess(@PathVariable String instanceId){
        ProcessInstance processInstance = processRuntime.delete(ProcessPayloadBuilder.delete().withProcessInstanceId(instanceId).build());
        return BaseResponse.success(processInstance);
    }

    @PostMapping("/suspendInstance/{instanceId}")
    public BaseResponse suspendInstance(@PathVariable String instanceId){
        ProcessInstance processInstance = processRuntime.suspend(ProcessPayloadBuilder.suspend().withProcessInstanceId(instanceId).build());
        return BaseResponse.success(processInstance);
    }

    @PostMapping("/resumeInstance/{instanceId}")
    public BaseResponse resumeInstance(@PathVariable String instanceId){
        ProcessInstance processInstance = processRuntime.resume(ProcessPayloadBuilder.resume().withProcessInstanceId(instanceId).build());
        return BaseResponse.success(processInstance);
    }

}
